package com.nulldev.util.web.YouTubeExtractor.extractors.util;

import static com.nulldev.util.web.YouTubeExtractor.comments.YTComments.find_value;

import java.io.File;
import java.util.List;

import com.nulldev.util.JVM.Arguments;
import com.nulldev.util.VariableAPI.ArrayUtils;
import com.nulldev.util.VariableAPI.MathUtil;
import com.nulldev.util.VariableAPI.StringsUtil;
import com.nulldev.util.VariableAPI.util.strings.splitters.Splitters;
import com.nulldev.util.concurrency.threadIt.v4.emapi.ExecutorManager;
import com.nulldev.util.concurrency.threadIt.v4.emapi.uft.Executable;
import com.nulldev.util.data.Variables;
import com.nulldev.util.data.Arrays.arrays.FastLists;
import com.nulldev.util.internal.backport.concurrency9.Lists;
import com.nulldev.util.io.file.FileUtil;
import com.nulldev.util.languages.json.uniapi.UniJsonIterableValue;
import com.nulldev.util.languages.json.uniapi.UniJsonValue;
import com.nulldev.util.logging.Logger;
import com.nulldev.util.logging.LoggerFactory;
import com.nulldev.util.manage.MarkedForRemoval;
import com.nulldev.util.web.YouTubeExtractor.YouTubeExtractorConstants;
import com.nulldev.util.web.YouTubeExtractor.items.YouTubeChapterEntry;
import com.nulldev.util.web.YouTubeExtractor.items.YouTubeVideoHeatmap;
import com.nulldev.util.web.YouTubeExtractor.util.YouTubeExtractorUtil;

public class SharedExtractorUtil {

	protected static final String IOS_CLIENT_VERSION = "19.04.3";
	protected static final String IOS_MUSIC_CLIENT_VERSION = "6.37";
	protected static final String IOS_CREATOR_CLIENT_VERSION = "24.03.100";

	public static final int ANDROID_SDK_VERSION_YT = 34; /* 19.05.35 beta targets API 34 */

	private static final Logger log = LoggerFactory.getLoggerD(Arguments.hasArgument("--debug", "--YouTubeExtractor.debug", "--SharedExtractorUtil.debug"));

	public static String getXSRFToken(final String html) {
		try {
			String s = find_value(html, "-XSRF_TOKEN", 3);
			if (s != null && !s.isEmpty()) {
				if (s.contains("html")) {
					return StringsUtil.replace(StringsUtil.substringBetweenF(html, "\"-XSRF_TOKEN\":", "\",\"", YouTubeExtractorConstants.XSRF_TOKEN),
							"\\u003d", "=");
				} else
					return StringsUtil.replace(s, "\\u003d", "=");
			}
			s = find_value(html, "XSRF_TOKEN", 3);
			if (s != null && !s.isEmpty()) {
				if (s.contains("html")) {
					return StringsUtil.replace(StringsUtil.substringBetweenF(html, "\"XSRF_TOKEN\":", "\",\"", YouTubeExtractorConstants.XSRF_TOKEN), "\\u003d",
							"=");
				} else
					return StringsUtil.replace(s, "\\u003d", "=");
			}
			log.warn("Failed to get local XSRF_TOKEN!");
			return YouTubeExtractorConstants.XSRF_TOKEN;
		} catch (Exception e) {
			return YouTubeExtractorConstants.XSRF_TOKEN;
		}
	}

	public static boolean is360(final String _pr) {
		return _pr.contains("https://s.youtube.com/api/stats/qoe?cat=spherical") || _pr.contains("\"projectionType\":\"MESH\"");
	}

	public static List<YouTubeChapterEntry> getChapters(final UniJsonValue ytInitialData) {
		if (ytInitialData == null || ytInitialData.isNull())
			return Lists.of();
		if (ytInitialData.contains("engagementPanels") && ytInitialData.get("engagementPanels").isArray()) {
			final UniJsonValue first = ytInitialData.get("engagementPanels").first();
			if (first.contains("engagementPanelSectionListRenderer")) {
				final UniJsonValue engagementPanelSectionListRenderer = first.get("engagementPanelSectionListRenderer");
				if (engagementPanelSectionListRenderer.contains("panelIdentifier") && engagementPanelSectionListRenderer.getString("panelIdentifier", "null")
						.equals("engagement-panel-macro-markers-description-chapters")) {
					final UniJsonValue contents = engagementPanelSectionListRenderer.get("content");
					final UniJsonValue isr = contents.get("sectionListRenderer").get("contents").asArray().first().get("itemSectionRenderer");
					final UniJsonValue isrc = isr.get("contents");
					final List<YouTubeChapterEntry> yt_chapters = FastLists.list();
					isrc.asArray().forEach((ren) -> {
						try {
							if (!ren.contains("elementRenderer")) {
								log.warn("Unknown object: ", ren);
								return;
							}
							final UniJsonValue elementRenderer = ren.get("elementRenderer");
							final UniJsonValue componentType = elementRenderer.get("newElement").get("type").get("componentType");
							final UniJsonValue renderer = componentType.get("model").get("macroMarkersListItemModel").get("renderer");
							final long time_millis = renderer.get("onTap").get("watchEndpoint").getLong("startTimeSeconds") * 1000;
							yt_chapters.add(new YouTubeChapterEntry(YouTubeExtractorUtil.getYTString(renderer.get("title")), time_millis));
						} catch (Exception ex) {
							log.derror("Failed to get chapter!", ex);
						}
					});
					return yt_chapters;
				}
			}
		}
		final UniJsonValue o = ytInitialData.safe("playerOverlays").safe("playerOverlayRenderer");
		if (o == null || o.isNull() || !o.contains("decoratedPlayerBarRenderer"))
			return Lists.of();
		final UniJsonValue mmpbr = o.safe("decoratedPlayerBarRenderer").safe("decoratedPlayerBarRenderer").safe("playerBar")
				.safe("multiMarkersPlayerBarRenderer");
		if (!mmpbr.contains("markersMap")) {
			log.derror("Failed to find 'markersMap'!");
			log.derror("Object: " + mmpbr);
			return Lists.of();
		}
		final UniJsonIterableValue chapters = mmpbr.safe("markersMap").asArray();
		UniJsonValue chaptersObj = null;
		for (final UniJsonValue entry : chapters) {
			if (entry.contains("key") && entry.getString("key", "null").equalsIgnoreCase("DESCRIPTION_CHAPTERS")) {
				chaptersObj = entry;
				break;
			}
		}
		final List<YouTubeChapterEntry> yt_chapters = FastLists.list();
		if (chaptersObj != null && !chaptersObj.isNull()) {
			final UniJsonValue arr = chaptersObj.get("value").get("chapters");
			if (arr == null || arr.isNull() || !arr.isArray())
				return Lists.of();
			arr.asArray().forEach((_chapter) -> {
				if (_chapter.hasValue("chapterRenderer")) {
					final UniJsonValue chapter = _chapter.get("chapterRenderer");
					yt_chapters.add(new YouTubeChapterEntry(YouTubeExtractorUtil.getYTString(chapter.get("title")), chapter.getLong("timeRangeStartMillis")));
				}
			});
		} else {
			final UniJsonValue chapters0 = ytInitialData.mget(
					"playerOverlays.playerOverlayRenderer.decoratedPlayerBarRenderer.decoratedPlayerBarRenderer.playerBar.chapteredPlayerBarRenderer.chapters");
			if (chapters0 != null && !chapters0.isNull()) {
				chapters0.asArray().forEach((_chapter) -> {
					if (_chapter.hasValue("chapterRenderer")) {
						final UniJsonValue chapter = _chapter.get("chapterRenderer");
						yt_chapters
								.add(new YouTubeChapterEntry(YouTubeExtractorUtil.getYTString(chapter.get("title")), chapter.getLong("timeRangeStartMillis")));
					}
				});
			}
		}
		return yt_chapters;
	}

	@Deprecated
	@MarkedForRemoval(reason = "Replaced by a dedicated storyboard parser.", plannedRemovalWhen = "2.3 or 2.2.10")
	public static String decipherStoryboard(final String spec) {
		final String[] chunks = spec.split("\\|");
		final String chunk0 = chunks[0].replace("_L$L", "_L1").replace("$N", "M0");
		final String chunk1 = StringsUtil.substringBetweenO(chunks[2] + "|", "#rs$", "|");
		final String url = chunk0 + "&sigh=rs%24" + chunk1;
		return url;
	}

	public static Executable<UniJsonValue> getYTInitialData(final String data) {
		/*
		 * Asynchronous submission isn't stable enough and breaks, DO NOT use here until
		 * functioning with heatmaps!
		 */
		return ExecutorManager.globalSubmit(() -> {
			if (StringsUtil.isBlank(data)) {
				return null;
			} else if (data.startsWith("[") && data.endsWith("]")) {
				return UniJsonValue.parseArray(data);
			} else if (data.startsWith("{") && data.endsWith("}")) {
				return UniJsonValue.parse(data);
			} else {
				final String initial_data_loose = StringsUtil.substringBetweenO(data, ">var ytInitialData = {", "};</");
				if (initial_data_loose == null) {
					final String initial_data_legacy = StringsUtil.substringBetweenO(data, "window[\"ytInitialData\"] = {", "}}};");
					if (initial_data_legacy == null) {
						__getYTInitialData__print_logs(data);
						throw new NullPointerException("Failed to fetch ytInitialData!");
					}
					return UniJsonValue.parse("{" + initial_data_legacy + "}");
				} else {
					return UniJsonValue.parse("{" + initial_data_loose + "}");
				}
			}
		});
	}

	private static void __getYTInitialData__print_logs(final String data) {
		try {
			final File tmp = File.createTempFile("yte-response-", ".html");

			FileUtil.writeFile(tmp, data);
		} catch (Exception _ignored) {
		}
	}

	public static Executable<String> getRawJSON(final String result) {
		return ExecutorManager.globalAsyncSubmit(() -> {
			final String rn = StringsUtil.substringBetweenO(result, ">var ytInitialPlayerResponse = ", "};");
			if (rn == null) {
				final String f = StringsUtil.substringBetweenO(result, "ytplayer.config = ", ";ytplayer.load");
				if (f == null || f.isEmpty())
					return null;
				final String r = ("{\"" + f);
				return r.substring(2, r.length());
			}
			return rn + "}";
		});
	}

	public static YouTubeVideoHeatmap getHeatmap(final UniJsonValue ytInitialData) {
		return getHeatmap(ytInitialData, false);
	}

	public static YouTubeVideoHeatmap getHeatmap(final UniJsonValue ytInitialData, final boolean disablePriorityPoint) {
		if (ytInitialData == null || ytInitialData.isNull())
			return null;
		final YouTubeVideoHeatmap value = __get_heatmap_marker_new(ytInitialData, disablePriorityPoint);
		if (value != null) {
			return value;
		} else {
			log.warn("Failed to get heatmap the first time, trying one last time!");
			return __get_heatmap_marker_old(ytInitialData, disablePriorityPoint);
		}

	}

	private static YouTubeVideoHeatmap __get_heatmap_marker_new(final UniJsonValue ytInitialData, final boolean disablePriorityPoint) {
		final UniJsonValue frameworkUpdates = ytInitialData.get("frameworkUpdates");
		if (frameworkUpdates == null || frameworkUpdates.isNull()) {
			log.error("Cannot find frameworkUpdates in ytInitialData.");
			return null;
		}
		final UniJsonValue entityBatchUpdate = frameworkUpdates.get("entityBatchUpdate");
		if (!entityBatchUpdate.contains("mutations")) {
			log.error("Cannot find mutations in entityBatchUpdate.");
			return null;
		}
		final UniJsonValue mutations = entityBatchUpdate.get("mutations").asArray();
		final UniJsonValue macroMarkersListEntity = YTX_GET_MUTATION(mutations, "macroMarkersListEntity");
		if (macroMarkersListEntity == null || macroMarkersListEntity.isNull()) {
			log.error("Cannot find macroMarkersListEntity in mutations.");
			return null;
		}
		final UniJsonValue markersList = macroMarkersListEntity.get("markersList");
		if (markersList == null || markersList.isNull()) {
			log.error("Cannot find markersList in macroMarkersListEntity.");
			return null;
		}
		if (!markersList.getString("markerType", "").equalsIgnoreCase("MARKER_TYPE_HEATMAP")) {
			log.error("Invalid markerType! [markerType=" + markersList.getString("markerType", "N/A") + "]");
			return null;
		}
		final UniJsonIterableValue heatMarkers = markersList.get("markers").asArray();
		final int size = heatMarkers.size();
		final Object[][] objs = new Object[(disablePriorityPoint ? size : size + 1)][];
		for (int i = 0; i < objs.length - 1; i++) {
			final UniJsonValue marker = heatMarkers.get(i);
			final Object[] seg = new Object[YouTubeVideoHeatmap.ENTRY_SET_SIZE];
			seg[0] = marker.getLong("durationMillis");
			seg[1] = marker.getLong("startMillis");
			seg[2] = marker.getFloat("intensityScoreNormalized");
			seg[3] = false;
			objs[i] = seg;
		}
		if (disablePriorityPoint)
			return new YouTubeVideoHeatmap(objs);
		if (!markersList.contains("markersDecoration")) {
			log.warn("Cannot progress with heatmap, markersList is missing markersDecoration. (providing stub)");
			log.derror("obj: " + markersList);
			__stub_peak_heatmap(objs, size);
			return new YouTubeVideoHeatmap(objs);
		}
		final UniJsonValue markersDecoration = markersList.get("markersDecoration");
		if (!markersDecoration.contains("timedMarkerDecorations")) {
			log.warn("Cannot progress with heatmap, markersDecoration is missing timedMarkerDecorations. (providing stub)");
			log.derror("obj: " + markersDecoration);
			__stub_peak_heatmap(objs, size);
			return new YouTubeVideoHeatmap(objs);
		}
		final UniJsonValue timedMarkerDecorations = markersDecoration.get("timedMarkerDecorations").asArray();
		if (timedMarkerDecorations.size() != 1) {
			log.warn("Cannot progress with heatmap, timedMarkerDecorations has more than one entity. (providing stub)");
			log.derror("obj: " + timedMarkerDecorations);
			__stub_peak_heatmap(objs, size);
			return new YouTubeVideoHeatmap(objs);
		}
		final UniJsonValue peakViewershipDecoration = timedMarkerDecorations.first();
		final Object[] seg = new Object[YouTubeVideoHeatmap.ENTRY_SET_SIZE];
		/* icon=UNKNOWN: thanks YouTube, very cool! */
		seg[0] = peakViewershipDecoration.getLong("decorationTimeMillis");
		seg[1] = peakViewershipDecoration.getLong("visibleTimeRangeStartMillis");
		seg[2] = 1f;
		seg[3] = true;
		objs[size] = seg;
		return new YouTubeVideoHeatmap(objs);
	}

	private static YouTubeVideoHeatmap __get_heatmap_marker_old(final UniJsonValue ytInitialData, final boolean disablePriorityPoint) {
		final UniJsonValue playerOverlays = ytInitialData.get("playerOverlays");
		if (playerOverlays == null) {
			log.error("Cannot find playerOverlays in ytInitialData.");
			return null;
		}
		final UniJsonValue playerOverlayRenderer = playerOverlays.get("playerOverlayRenderer");
		if (!playerOverlayRenderer.contains("decoratedPlayerBarRenderer")) {
			log.error("Cannot find decoratedPlayerBarRenderer in playerOverlayRenderer.");
			log.debug("playerOverlayRenderer: " + playerOverlayRenderer);
			return null;
		}
		final UniJsonValue decoratedPlayerBarRenderer = playerOverlayRenderer.get("decoratedPlayerBarRenderer").get("decoratedPlayerBarRenderer");
		if (!decoratedPlayerBarRenderer.contains("playerBar")) {
			log.error("Cannot find playerBar in ", decoratedPlayerBarRenderer);
			return null;
		}
		final UniJsonValue playerBar = decoratedPlayerBarRenderer.get("playerBar");
		if (!playerBar.contains("multiMarkersPlayerBarRenderer")) {
			log.error("Cannot find multiMarkersPlayerBarRenderer in ", playerBar);
			return null;
		}
		final UniJsonValue multiMarkersPlayerBarRenderer = playerBar.get("multiMarkersPlayerBarRenderer");
		if (!multiMarkersPlayerBarRenderer.contains("markersMap")) {
			log.error("Cannot find markersMap in multiMarkersPlayerBarRenderer.");
			log.debug("multiMarkersPlayerBarRenderer: " + multiMarkersPlayerBarRenderer);
			return null;
		}
		final UniJsonIterableValue markersMap = multiMarkersPlayerBarRenderer.get("markersMap").asArray();
		UniJsonValue mapInst = null;
		for (final UniJsonValue entry : markersMap) {
			if (entry.contains("key") && entry.getString("key", "null").equalsIgnoreCase("HEATSEEKER")) {
				mapInst = entry;
				break;
			}
		}
		if (mapInst == null) {
			log.error("Cannot find mapInst in markersMap.");
			log.debug("markersMap: " + markersMap);
			return null;
		}
		final UniJsonValue value;
		if (!mapInst.getString("key", "").equals("HEATSEEKER") && !mapInst.contains("heatmap")) {
			log.error("Cannot find HEATSEEKER in ", mapInst);
			return null;
		} else if (!mapInst.getString("key", "").equals("HEATSEEKER") && mapInst.contains("heatmap")) {
			log.dwarn("Cannot find HEATSEEKER but we know it's a heatmap...um.");
			value = mapInst.get("value");
		} else {
			value = mapInst.get("value");
		}
		final UniJsonValue heatmap = value.get("heatmap").get("heatmapRenderer");
		final UniJsonIterableValue heatMarkers = heatmap.get("heatMarkers").asArray();
		final int size = heatMarkers.size();
		final Object[][] objs = new Object[(disablePriorityPoint ? size : size + 1)][];
		for (int i = 0; i < objs.length - 1; i++) {
			final UniJsonValue marker = heatMarkers.get(i);
			if (!marker.contains("heatMarkerRenderer")) {
				log.warn("Unknown marker: " + marker);
				continue;
			} else {
				final UniJsonValue heatMarkerRenderer = marker.get("heatMarkerRenderer");
				final Object[] seg = new Object[YouTubeVideoHeatmap.ENTRY_SET_SIZE];
				seg[0] = heatMarkerRenderer.getLong("markerDurationMillis");
				seg[1] = heatMarkerRenderer.getLong("timeRangeStartMillis");
				seg[2] = heatMarkerRenderer.getFloat("heatMarkerIntensityScoreNormalized");
				seg[3] = false;
				objs[i] = seg;
			}
		}
		if (disablePriorityPoint)
			return new YouTubeVideoHeatmap(objs);
		if (!heatmap.contains("heatMarkersDecorations")) {
			log.warn("Cannot progress with heatmap, value is missing heatMarkersDecorations. (providing stub)");
			log.derror("value: " + value);
			__stub_peak_heatmap(objs, size);
			return new YouTubeVideoHeatmap(objs);
		}
		final UniJsonIterableValue heatMarkersDecorations = heatmap.get("heatMarkersDecorations").asArray();
		try {
			heatMarkersDecorations.forEach((marker) -> {
				if (marker.contains("timedMarkerDecorationRenderer")) {
					final UniJsonValue timedMarkerDecorationRenderer = marker.get("timedMarkerDecorationRenderer");
					final String icon = timedMarkerDecorationRenderer.getString("icon", "");
					if (icon.equals("AUTO_AWESOME")) {
						final Object[] seg = new Object[YouTubeVideoHeatmap.ENTRY_SET_SIZE];
						seg[0] = timedMarkerDecorationRenderer.getLong("decorationTimeMillis");
						seg[1] = timedMarkerDecorationRenderer.getLong("visibleTimeRangeStartMillis");
						seg[2] = 1f;
						seg[3] = true;
						objs[size] = seg;
					} else {
						log.warn("Unknown icon: " + icon);
						return;
					}
				} else {
					log.warn("Unknown marker decoration: " + marker);
					return;
				}
			});
			return new YouTubeVideoHeatmap(objs);
		} catch (Exception ex) {
			log.warn("Cannot progress with heatmap, failed to get peak. [reason=exception]");
			log.error(ex);
			__stub_peak_heatmap(objs, size);
			return new YouTubeVideoHeatmap(objs);
		}
	}

	private static void __stub_peak_heatmap(final Object[][] objs, final int size) {
		final Object[] seg = new Object[YouTubeVideoHeatmap.ENTRY_SET_SIZE];
		seg[0] = -1;
		seg[1] = -1;
		seg[2] = 1f;
		seg[3] = true;
		objs[size] = seg;
	}

	public static UniJsonValue YTX_GET_IDENTIFIER(final UniJsonValue array, final String identifier) {
		Variables.requireNonNull(array, "array");
		Variables.requireNonNull(identifier, "identifier");
		if (!array.isArray() || array.isNull())
			return null;
		for (final UniJsonValue uv : array.asArray()) {
			if (!uv.contains("elementRenderer"))
				continue;
			final UniJsonValue elementRenderer = uv.get("elementRenderer");
			if (!elementRenderer.contains("newElement")) {
				log.warn("YTX_GET_IDENTIFIER: Unknown object: " + elementRenderer);
				continue;
			} else {
				final UniJsonValue newElement = elementRenderer.get("newElement");
				final UniJsonValue props = newElement.get("properties");
				final UniJsonValue idProps = props.get("identifierProperties");
				final String id = idProps.getString("identifier");
				final String[] ids = Splitters.splitString(id, "|");
				if (ArrayUtils.StringArrayUtils.containsString(ids, identifier))
					return newElement.get("type");
			}
		}
		return null;
	}

	public static UniJsonValue YTX_GET_MUTATION_IDENTIFIER(final UniJsonValue array, final String identifier) {
		Variables.requireNonNull(array, "array");
		Variables.requireNonNull(identifier, "identifier");
		if (!array.isArray() || array.isNull())
			return null;
		for (final UniJsonValue uv : array.asArray()) {
			if (!uv.contains("entityKey"))
				continue;
			final String key = uv.getString("entityKey");
			if (identifier.equals(key))
				return uv;
		}
		return null;
	}

	public static UniJsonValue YTX_GET_MUTATION(final UniJsonValue array, final String objectNameToFind) {
		Variables.requireNonNull(array, "array");
		Variables.requireNonNull(objectNameToFind, "objectNameToFind");
		if (!array.isArray() || array.isNull())
			return null;
		for (final UniJsonValue uv : array.asArray()) {
			if (!uv.contains("payload"))
				continue;
			final UniJsonValue payload = uv.get("payload");
			if (payload.contains(objectNameToFind))
				return payload.get(objectNameToFind);
		}
		return null;
	}

	public static boolean isDVR(final UniJsonValue metadataCore) {
		if (metadataCore.contains("microformat") && metadataCore.get("microformat").contains("playerMicroformatRenderer")) {
			final UniJsonValue playerMicroformatRenderer = metadataCore.get("microformat").get("playerMicroformatRenderer");
			if (playerMicroformatRenderer.contains("liveBroadcastDetails")) {
				return !playerMicroformatRenderer.get("liveBroadcastDetails").bool("isLiveNow");
			} else {
				log.dwarn("[isDVR] Missing liveBroadcastDetails. Falling back...");
				return metadataCore.get("videoDetails").bool("isPostLiveDvr", false);
			}
		} else {
			return metadataCore.get("videoDetails").bool("isPostLiveDvr", false);
		}
	}

	public static long getLikeCountString(final UniJsonValue ytInitialData) {
		if (ytInitialData == null || ytInitialData.isNull()) {
			return -1L;
		}

		if (ytInitialData.contains("contents")) {
			final UniJsonValue contents = ytInitialData.get("contents");
			if (contents.contains("twoColumnWatchNextResults")) {
				final UniJsonValue watchNextResults = contents.get("twoColumnWatchNextResults");
				final UniJsonValue results = watchNextResults.get("results").get("results").get("contents");
				final UniJsonValue videoPrimaryInfoRenderer = results.arrayGetContains("videoPrimaryInfoRenderer").get("videoPrimaryInfoRenderer");
				final UniJsonValue videoActions = videoPrimaryInfoRenderer.get("videoActions").get("menuRenderer");
				final UniJsonValue topLevelButtons = videoActions.get("topLevelButtons");
				final UniJsonValue segmentedLikeDislikeButtonViewModel = topLevelButtons.arrayGetContains("segmentedLikeDislikeButtonViewModel")
						.get("segmentedLikeDislikeButtonViewModel");

				if (segmentedLikeDislikeButtonViewModel.contains("likeButtonViewModel")) {
					final UniJsonValue likeButtonViewModel = segmentedLikeDislikeButtonViewModel.get("likeButtonViewModel").get("likeButtonViewModel");

					if (likeButtonViewModel.contains("toggleButtonViewModel")) {
						final UniJsonValue toggleButtonViewModel = likeButtonViewModel.get("toggleButtonViewModel").get("toggleButtonViewModel");
						final UniJsonValue defaultButtonViewModel = toggleButtonViewModel.get("defaultButtonViewModel").get("buttonViewModel");

						return MathUtil.safeParseL(StringsUtil.onlyNumbers(defaultButtonViewModel.getString("accessibilityText")), -1L);
					} else {
						log.error("[getLikeCountString] Failed to find toggleButtonViewModel!");
						return -1L;
					}
				} else {
					log.error("[getLikeCountString] Failed to find likeButtonViewModel!");
					return -1L;
				}
			} else {
				log.error("[getLikeCountString] Failed to find twoColumnWatchNextResults!");
				return -1L;
			}
		} else {
			log.error("[getLikeCountString] Failed to find contents!");
			log.derror(ytInitialData);
			return -1L;
		}
	}
}
